package com.luhe.midi.mthd;

import com.luhe.midi.helper.ByteUtil;
import org.apache.log4j.Logger;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

//mid文件头部：[M t h d 0 0 0 6]头部  [0 1]类型  [0 0]音轨数目 [0 0] 四分音符时间
public class MThd {
    //日志
    Logger logger = Logger.getLogger(this.getClass().getName());

    //midi文件头部
    public char head[] = {'M', 'T', 'h', 'd'};

    //Mid文件类型:单音轨00 、多音轨同步01（最常见）、多音轨不同步02
    public int midiType;

    //轨道数目：实际音轨加上一个全局音轨，不能超过16
    public int mtrkNum;

    //Mid时间间隔：一般为120(0x78) ，一个四分音符的时间
    public int tickTime;

    //内部字节数据
    private byte[] innerBytes = new byte[14];

    //获取内部字节
    public byte[] getInnerBytes() {
        //先写到byteArrayOutputStream,再写出输出流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        //M T h d 0 0 0 6
        byteArrayOutputStream.write('M');
        byteArrayOutputStream.write('T');
        byteArrayOutputStream.write('h');
        byteArrayOutputStream.write('d');
        byteArrayOutputStream.write(0);
        byteArrayOutputStream.write(0);
        byteArrayOutputStream.write(0);
        byteArrayOutputStream.write(6);

        //midi类型
        byteArrayOutputStream.write(0);
        byteArrayOutputStream.write((byte) this.midiType);

        //midi轨道数目
        byteArrayOutputStream.write(0);
        byteArrayOutputStream.write((byte) this.mtrkNum);

        //midi基本时间
        byteArrayOutputStream.write(0);
        byteArrayOutputStream.write((byte) this.tickTime);

        //获取字节
        this.innerBytes = byteArrayOutputStream.toByteArray();

        return this.innerBytes;
    }


    public void writeOutputStream(OutputStream outputStream) throws IOException {

        //计算内部字节
        this.innerBytes = getInnerBytes();

        //调试输出
        logger.info("写出头部：" + ByteUtil.printByte(this.innerBytes, 0, 7));
        logger.info("写出类型：" + ByteUtil.printByte(this.innerBytes, 8, 9));
        logger.info("轨道数目：" + ByteUtil.printByte(this.innerBytes, 10, 11));
        logger.info("基本时间：" + ByteUtil.printByte(this.innerBytes, 12, 13));


        //写出数据
        outputStream.write(this.innerBytes);


    }

    //从字节获取
    public MThd read(InputStream inputStream) throws IOException {
        this.innerBytes = new byte[14];
        inputStream.read(this.innerBytes);
        this.midiType = this.innerBytes[9];
        this.mtrkNum = this.innerBytes[11];
        this.tickTime = this.innerBytes[13];
        logger.info("头部字节：" + ByteUtil.printByte(this.innerBytes));
        logger.info("读入头部：" + ByteUtil.printByte(this.innerBytes, 0, 7));
        logger.info("读入类型：" + ByteUtil.printByte(this.innerBytes, 8, 9));
        logger.info("轨道数目：" + ByteUtil.printByte(this.innerBytes, 10, 11));
        logger.info("基本时间：" + ByteUtil.printByte(this.innerBytes, 12, 13));

        return this;
    }


}
